﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using I3.AgenteIA.Aplicacao.DTOs;
using I3.AgenteIA.Dominio.Gramatica;
using I3.AgenteIA.Dominio;

namespace I3.AgenteIA.Aplicacao
{
    public class AnalisarProcessamentoMorfologico
    {
        /// <summary>
        /// Armazena a instancia do interpreter da oração
        /// </summary>
        private IOracaoInterpreter _oracaoInterpreter;

        /// <summary>
        /// Armazena a instancia do interpreter da sentenca
        /// </summary>
        private ISentencaInterpreter _sentencaInterpreter;

        /// <summary>
        /// Armazena a instancia do interpreter do elemento
        /// </summary>
        private IElementoInterpreter _elementoInterpreter;

        /// <summary>
        /// Construtor padrão da fachada de aplicação
        /// </summary>
        public AnalisarProcessamentoMorfologico(IOracaoInterpreter oracaoInterpreter, ISentencaInterpreter sentencaInterpreter, IElementoInterpreter elementoInterpreter)
        {
            _oracaoInterpreter = oracaoInterpreter;
            _sentencaInterpreter = sentencaInterpreter;
            _elementoInterpreter = elementoInterpreter;
        }

        /// <summary>
        /// Recupera os dados sintéticos da analise morfologica realizada no texto
        /// </summary>
        /// <param name="texto">Texto que será analisado</param>
        /// <returns>Informações sintéticas do processamento</returns>
        public SinteseMorfologicaDTO ObterSinteseDoProcessamento(string texto)
        {
            SinteseMorfologicaDTO sinteseMorfologicaDTO = null;
            DateTime? inicio = null, termino = null;

            try
            {
                // Data e hora de inicio do processo
                inicio = DateTime.Now;

                // Realiza uma primeira analise no texto informado.
                // caso o valor informado seja vazio ou nulo, retorna as informações da sintese zeradas.
                if (String.IsNullOrEmpty(texto))
                {
                    sinteseMorfologicaDTO = new SinteseMorfologicaDTO() { QtdeDeOracoes = 0, QtdeDeSentencas = 0, QtdeDeElementos = 0 };
                }
                else
                {
                    Oracao oracao = _oracaoInterpreter.Interpretar(texto);
                    IEnumerable<Sentenca> sentencas = _sentencaInterpreter.Interpretar(oracao);
                    List<Elemento> elementos = new List<Elemento>();
                    foreach (Sentenca sentenca in sentencas)
                        elementos.AddRange(_elementoInterpreter.Interpretar(sentenca));

                    // retorna as informações sisteticas geradas pelos interpreters
                    sinteseMorfologicaDTO = new SinteseMorfologicaDTO()
                    {
                        QtdeDeOracoes = 1,
                        QtdeDeSentencas = sentencas.Count(),
                        QtdeDeElementos = elementos.Count(),
                    };
                }

                // Define a data do processamento da sintese 
                termino = DateTime.Now;

                // Retorna as informações sintéticas identificadas durante o processamento.
                return sinteseMorfologicaDTO;
            }
            finally
            {
                // Verifica se as variaveis internas obrigatórias
                // foram inicializadas corretamente
                if (sinteseMorfologicaDTO == null) throw new NullReferenceException("O objeto DTO não foi inicializado corretamente");
                if (!inicio.HasValue) throw new NullReferenceException("A data de inicio não foi inicializada corretamente");
                if (!termino.HasValue) throw new NullReferenceException("A data de termino não foi inicializada corretamente");

                // Define os valores de analise do tempo de execução 
                // do processamento da analise morfologica.
                sinteseMorfologicaDTO.Oracao = texto;
                sinteseMorfologicaDTO.InicioProcessamento = inicio.Value;
                sinteseMorfologicaDTO.TerminoProcessamento = termino.Value;
                sinteseMorfologicaDTO.TempoExecucao = termino.Value - inicio.Value;
            }
        }

        /// <summary>
        /// Recupera os dados dos elementos pertencentes a oração
        /// </summary>
        public IEnumerable<ElementoDTO> ObterMorfemas()
        {
            return null;
        }
    }
}
